/***************************************************************************
 //* Foxit Software Inc.
 //* Copyright(C) 2005-2012, all rights reserved.
 //*
 //* The following code is copyrighted and contains proprietary information
 //* and trade secrets of Foxit Software Inc.                                                      *
 ***************************************************************************/

/**
 * PDF页面显示
 */

define(function (require, exports, module) {
    require('../ViewLevel.js');
    var PDFRect = require('../Math/Rect');
    var PDFPoint = require('../Math/Point');
    var Config = require("../Config");
    var RectUtils = WebPDF.RectUtils;
    
    
    /**
     * Create an new PDFPageView object.
     * @class Represents a control for displaying a page.
     * @constructor
     * @param {WebPDF.IPDFPage} pdfPage     PDF page object
     * @param {WebPDF.PDFView.PDFDocView} docView Doc view object
     * @return A page view
     */
    var PDFPageView = function (readerApp, docView, pdfPage) {
        if (!pdfPage) {
            $.error("PDF page can not be null to create page view!");
        }
        
        this.readerApp = readerApp;
        this.pdfPage = pdfPage;
        this.docView = docView;    
        this.scale =  docView.getScale();      
        
        
        this.pageViewWidth = 0;
        this.pageViewHeight = 0;
        this.isCreated = false;  
        var pageIndex = pdfPage.getPageIndex();
        this.pageContainerID = docView.getPageViewContainerID(pageIndex);
        this.pageBGImgID = docView.getPageBackgroundImgID(pageIndex); //背景图
        this.wrapPageID = docView.getWrapPageID(pageIndex);
        this.pageLoaderImgID = docView.getPageLoaderImageID(pageIndex);
        this._isPageLoadError = false;
        
        var elements = this.elements =  [];
        
        elements["#" + this.pageContainerID] = "pageContainer";        
        elements["#" + this.pageBGImgID] = "pageBGImg";
        elements["#" + this.wrapPageID] = "wrapPage";
        elements["#" + this.pageLoaderImgID] = "pageLoaderImg";       
        return new PDFPageViewInner(this);
	};
    
    var PDFPageViewInner = Backbone.View.extend({        
        
         initialize : function(){   
             this.isCreated = false;
             this._isDimensionUpdated = false;
             this.isModified = false;
             this.isThumbnailLoaded = false;
       
         },
        
        
        /**
         * @description Returns the width of current PDF page.
         * @return {Number} The width of current PDF page.
         */
        getPDFPageWidth : function () {
            return this.pdfPage.getPageWidth();
        },
        /**
         * @description Returns the height of current PDF page.
         * @return {Number} The height of current PDF page.
         */
        getPDFPageHeight : function () {
            return this.pdfPage.getPageHeight();
        },
        /**
         * Set the width of PDF page view
         * @param {Number} Width width of PDF page view to set.
         * @ignore
         */
        setPageViewWidth : function (width) {
            if (!isNaN(width)) {
                this.pageViewWidth = width;
            }
        },
        /**
         * @description Returns the height of current page view.
         * @return {Number} The height of current page view.
         */
        getPageViewHeight : function () {
            return this.pageViewHeight;
        },
        /**
         * Set the height of PDF page view
         * @param {Number} Height height of PDF page view to set.
         * @ignore
         */
        setPageViewHeight : function (height) {
            if (!isNaN(height))   {
                this.pageViewHeight = height;
            }
        },

         /**
         * Returns the id of DOM element for current page.
         * @returns {string} The id of DOM element for current page.
         */
        getPageViewContainerID : function () {
            return this.pageContainerID;
        },
        
        getPageViewContainer : function(){
           return this.pageContainer;  
        },
        /**
         * Get background image id of page view.
         * @returns {String} Background image id of page view.
         * @ignore
         */
        getPageBackgroundImgID : function () {
            return this.pageBGImgID;
        },
        /**
         * 获取Wrap ID，通常用来存放页面读取失败的情况下的失败信息
         * @returns {string}
         * @ignore
         */
        getWrapPageID : function () {         
            return this.wrapPageID;
        },
        
        getWrapPage : function () {         
            return this.wrapPage;
        },
        /**
         * Get id of loader image.
         * @returns {string} id of loader image.
         * @ignore
         */
        getPageLoaderImageID : function () {
            return this.pageLoaderImgID;
        },
        
        getPageLoaderImage : function () {
            return this.pageLoaderImg;
        },
        
         /**
         * Get background image id of page view.
         * @returns {String} Background image id of page view.
         * @ignore
         */
        getPageBackgroundImg : function () {
            return this.pageBGImg;
        },                 
         /**
         * 设置page对应的div是否创建的状态;
         * @param isCreated
         * @ignore
         */
        setContentCreatedState : function (isCreated) {
            this.isCreated = isCreated;
        },
        /**
         * 判断页面是否已经创建
         * @returns {boolean} 如果页面已经创建，返回true，否则返回false
         * @ignore
         */
        isContentCreated : function () {
            return this.isCreated;
        },
                /**
         * Check whether the dimension of current page has been updated according to current zoom level.
         * @returns {boolean}
         * @ignore
         */
        isDimensionUpdated : function () {
            return this._isDimensionUpdated;
        },
        /**
         * 设置页面大小的更新状态
         * @param isUpdated 页面大小的更新状态
         * @ignore
         */
        setDimensionUpdated : function (isUpdated) {
            this._isDimensionUpdated = isUpdated;
        },
           /**
         * Update dimension of page according to current zoom level.
         * @ignore
         */
        updateDimension : function () {
            var scale = this.docView.getScale() * this.readerApp.getPixelsPerPoint();
            var pageViewWidth = this.getPDFPageWidth() * scale;
            var pageViewHeight = this.getPDFPageHeight() * scale;
            this.setPageViewWidth(pageViewWidth);
            this.setPageViewHeight(pageViewHeight);

            var scrollBarWidth = this.docView.getRealScrollBarWidth();
            var leftMargin = (this.docView.getDocViewWidth() - pageViewWidth - scrollBarWidth ) / 2;
            if (leftMargin < 0)
                leftMargin = 0;
            
            this.getPageViewContainer().css({
                height: pageViewHeight,
                width: pageViewWidth,
                "margin-left": leftMargin
            });
            /*
            if (_isPageLoadError) {
                $("#" + _wrapPageID).children("div").css(cacleErrorPageImgRect());
            }*/
        },
        
         /**
         * Get current scale.
         * @returns {Number|String}
         * @ignore
         */
        getScale : function () {
            return this.scale;
        },
        /**
         * Set current scale.
         * @param {Number|String} scale
         * @ignore
         */
        setScale : function (scale) {
            this.scale = scale;
        },
        
         /**
         * @description Check whether the page is loaded successfully.
         * @return {Boolean} Return true if the page is loaded successfully, otherwise return false.
         */
        isPageLoaded : function () {
            return this._isPageLoaded;
        },
        /**
         * Set loaded state of page.
         * @param {Boolean} isLoad
         * @ignore
         */
        setPageLoaded : function (isLoad) {
            this._isPageLoaded = isLoad;
        },
        
         /**
         * @description Returns the width of current page view.
         * @return {Number} The width of current page view.
         */
        getPageViewWidth : function () {
            return this._pageViewWidth;
        },
        
         /**
         * @description Return the index of this page.
         * @return {Number} The index of this page.
         */
        getPageIndex : function () {
            return this.pdfPage.getPageIndex();
        },
        
         /**
         * @description check whether the page is a thumbnail.
         * @return {Boolean} return true if the page is a thumbnail, otherwise return false.
         * @ignore
         */
        isThumb : function () {
            return false;
        },

        /**
         * 加载页面图片时，先加载缩略图，后加载页面图片，该函数用来判断缩略图是否已经加载；
         * @returns {boolean}
         * @ignore
         */
        isThumbnailLoaded : function(){
          return this.isThumbnailLoaded;
        },

        setThumbnailLoaded : function(isLoaded){
            this.isThumbnailLoaded = isLoaded;
        },
        
        /**
         * @description Returns the current PDFDocView object.
         * @return {WebPDF.PDFView.PDFDocView} The current PDFDocView object.
         */
        getDocView : function () {          
            return this.docView;
        },
        
         /**
         * @description Returns the PDFPage object of current page view.
         * @return {WebPDF.IPDFPage} The PDFPage object.
         */
        getPDFPage : function () {
            return this.pdfPage;
        },       
        
       
        /**
         * Show page.
         * @ignore
         */
        show : function () {         
            this.getWrapPage().addClass("fwr-hidden");
            this.getPageBackgroundImg().removeClass("fwr-hidden");
            this.getPageLoaderImage().hide();
        },
        
        render : function(pageHtml){
            this.$el.append(pageHtml);
            this.$el.css({"width" : "100%"}).addClass("fwr-page-invisible");
            this.refreshElements();
        },     

        /**
         * Show error image by specified image url.
         * @param errorImageUrl image url for error.
         * @ignore
         */
        showErrorPage : function (errorImageUrl) {
            var jqWrap = this.getwrapPage();
            jqWrap.html('');
            jqWrap.removeClass("fwr-hidden");
            this.getPageBackgroundImg().addClass("fwr-hidden");
            this.getPageLoaderImage().hide();       

            var rectData = this._cacleErrorPageImgRect();
            var html = "<div style='position:absolute;width:" + rectData.width + "px;height:" + rectData.height + "px;margin-left:"
                + rectData["margin-left"] + "px;margin-top:" + rectData["margin-top"] + "px'><img alt='' src='"
                + errorImageUrl + "'  style='width:100%;height:100%'></div>";
            jqWrap.append(html);
        },

       
        /**
         * @description Check whether there is an error when load this page.
         * @return {Boolean} Return true if there is an error when load this page, otherwise return false.
         */
        isPageLoadError : function () {
            return this._isPageLoadError;
        },
        /**
         * Set load error state of page.
         * @param {Boolean} isLoadError
         * @ignore
         */
        setPageLoadError : function (isLoadError) {
            this._isPageLoadError = isLoadError;
        },
        /**
         * @description Transform a rect from PDF space(user space) to device space.
         * @param {WebPDF.PDFRect} rect The rect to transform.
         * @param isScale If set this parameter to true, the rect will be multiplied by the current zoom level.
         * @returns {PDFRect} An new rect in device space.
         */
        pdfToDoc : function (rect, isScale) {
            RectUtils.normalize(rect);
            var oldWidth = RectUtils.width(rect);
            var oldHeight = RectUtils.height(rect);
            var newRect = new PDFRect(0, 0, 0, 0);
            var scale = this.getScale();
            var pixelsPerPoint = this.readerApp.getPixelsPerPoint();
            newRect.left = (rect.left * pixelsPerPoint) * scale;
            if (isScale) {
                newRect.right = newRect.left + oldWidth * pixelsPerPoint * scale;
            }
            else{
                newRect.right = newRect.left + oldWidth * pixelsPerPoint;
            }
            newRect.top = (rect.top) * pixelsPerPoint * scale;
            newRect.top = _pageViewHeight - newRect.top;
            if (isScale)  {
                newRect.bottom = newRect.top + oldHeight * pixelsPerPoint * scale;
            }
            else {
                newRect.bottom = newRect.top + oldHeight * pixelsPerPoint;
            }
            return newRect;
        },
        /**
         * Transform a rect from device space to PDF space(user space).
         * @param {WebPDF.PDFRect} rect The rectangle to transform
         * @param isScale If set this parameter to true, the rect will be divided by the current zoom level.
         * @returns {PDFRect} An new rect in PDF space.
         */
        docToPDF : function(rect, isScale)
        {
            var oldWidth = RectUtils.width(rect);
            var oldHeight = RectUtils.height(rect);
            var newRect = new PDFRect(0, 0, 0, 0);
            var scale = _self.getScale();
            if(!isScale) {
                scale = 1;
            }
            var pixelsPerPoint = _readerApp.getPixelsPerPoint();
            newRect.left = rect.left / (pixelsPerPoint * scale);
            newRect.right = newRect.left + oldWidth/(pixelsPerPoint * scale);
            newRect.top = _self.getPDFPageHeight() - (rect.top / (pixelsPerPoint * scale));
            newRect.bottom = newRect.top - oldHeight/(pixelsPerPoint * scale);
            return newRect;
        },

        /**
         * @description Transform point from device space to PDF space(user space).
         * @param {WebPDF.PDFPoint} docPt The point to transform.
         * @returns {PDFPoint} An new point in PDF space.
         */
        docPtToPDF : function (docPt) {
            var scale = this.getScale();
            var pixelsPerPt = this.readerApp.getPixelsPerPoint();
            var pdfPt = new PDFPoint(0, 0);
            pdfPt.x = docPt.x / (pixelsPerPt * scale);
            pdfPt.y = (this.pageViewHeight - docPt.y) / (pixelsPerPt * scale);
            return pdfPt;
        },
        /**
         * Transform point from PDF space(user space) to device space.
         * @param pdfPt The point to transform.
         * @returns {PDFPoint} An new point in device space.
         */
        pdfPtToDoc : function(pdfPt)
        {
            var scale = this.getScale();
            var pixelsPerPt = this.readerApp.getPixelsPerPoint();
            var docPt = new PDFPoint(0, 0);
            docPt.x = pdfPt.x * (pixelsPerPt * scale);
            docPt.y = (this.getPDFPageHeight() - pdfPt.y) * (pixelsPerPt * scale);
            return docPt;
        },
        /**
         * Get offset from parent div.
         * @returns {{left: number, top: number}}
         * @ignore
         */
        getPageViewDivOffset : function () {
            var e =  this.$el;
            var $docViewContainer = this.docView.$el;
            var docViewOffset = $docViewContainer.offset();
            var offset = e.offset();
           /* var eleTop = 0, eleLeft = 0;
            eleTop += e.get(0).offsetTop;
            eleLeft += e.get(0).offsetLeft;
            return { left: eleLeft, top: eleTop };*/
            return { left: offset.left - docViewOffset.left, top: offset.top - docViewOffset.top};
        },
        /**
         * Get rect of page view.
         * @returns {WebPDF.PDFRect} rect of page view.
         */
        getPageViewRect : function () {
            var offset = this.getPageViewDivOffset();
            return new WebPDF.PDFRect(offset.left, offset.top, offset.left + this.getPageViewWidth()
                , offset.top + this.getPageViewHeight());
        },
        /**
         * 根据位置和类型取annot，其中类型可以为空
         * @private
         * */
        getAnnotAtPoint : function (event, annotType) {
            return null;
        },
        getFocusAnnot : function () {
            return null;
        },
        setFocusAnnot : function (annot) {
        },
        /**
         * Check whether page content has been modified.
         * @returns {boolean} return true if page content has been modified.
         * @ignore
         */
        isModified : function () {
            return this._isModified;
        },
        /**
         * Set state of page content modification.
         * @param{Boolean} isModified
         * @ignore
         */
        setModified : function (isModified) {
            this._isModified = isModified;
        },        
        
        //私有函数
       _cacleErrorPageImgRect : function() {       
            var zoomX = Config.defaults.errPageImgWidth / this.pageViewWidth;
            var zoomY = Config.defaults.errPageImgHeight / this.pageViewHeight;
            var zoom = zoomX >= zoomY ? zoomX : zoomY;
            zoom = zoom > 1 ? zoom : 1;
            var realWidth = Config.defaults.errPageImgWidth / zoom;
            var realHeight = Config.defaults.errPageImgHeight / zoom;
            var marginLeft = (this.pageViewWidth - realWidth) / 2;
            var marginTop = (this.pageViewHeight - realHeight) / 2;
            return {"width":realWidth, "height":realHeight,"margin-left":marginLeft,"margin-top":marginTop};
       }
    
    })

   
    module.exports = PDFPageView;
});